#include <iostream>
#include <string>
#include <vector>
#include <fstream>
#include <sstream>
#include <algorithm>
#include <array>
#include <memory>
#include <stdexcept>
#include <time.h>
#include <curl/curl.h>
#include <crypt.h>
#include <thread>
#include <mutex>
#include <queue>
#include <future>
#include <chrono>
#include <iomanip>
#include <map>
#include <set>

// 漏洞类型枚举
enum VulnerabilityType {
    SQL_INJECTION,
    XSS,
    FILE_INCLUSION,
    COMMAND_INJECTION,
    CSRF,
    WEAK_PASSWORD,
    PERMISSION_ISSUE,
    UNPATCHED_SOFTWARE,
    UNSAFE_CONFIGURATION,
    OPEN_REDIRECT,
    SENSITIVE_DATA_EXPOSURE
};

// 漏洞严重程度枚举
enum Severity {
    LOW,
    MEDIUM,
    HIGH,
    CRITICAL
};

// 漏洞结构体
struct Vulnerability {
    std::string target;
    VulnerabilityType type;
    Severity severity;
    std::string description;
    std::string evidence;
    std::string recommendation;
    time_t found_time;
    std::string request_payload;
    std::string response_snippet;

    // 转换类型为字符串
    std::string type_to_string() const {
        switch(type) {
            case SQL_INJECTION: return "SQL注入漏洞";
            case XSS: return "跨站脚本漏洞(XSS)";
            case FILE_INCLUSION: return "文件包含漏洞";
            case COMMAND_INJECTION: return "命令注入漏洞";
            case CSRF: return "跨站请求伪造(CSRF)";
            case WEAK_PASSWORD: return "弱密码漏洞";
            case PERMISSION_ISSUE: return "权限配置问题";
            case UNPATCHED_SOFTWARE: return "未打补丁的软件";
            case UNSAFE_CONFIGURATION: return "不安全的配置";
            case OPEN_REDIRECT: return "开放重定向漏洞";
            case SENSITIVE_DATA_EXPOSURE: return "敏感信息泄露";
            default: return "未知漏洞";
        }
    }

    // 转换严重程度为字符串
    std::string severity_to_string() const {
        switch(severity) {
            case LOW: return "LOW";
            case MEDIUM: return "MEDIUM";
            case HIGH: return "HIGH";
            case CRITICAL: return "CRITICAL";
            default: return "未知";
        }
    }
};

// 扫描结果类
class ScanResult {
private:
    std::vector<Vulnerability> vulnerabilities;
    int total_tests;
    int passed_tests;
    std::mutex mtx;

public:
    ScanResult() : total_tests(0), passed_tests(0) {}

    void add_vulnerability(const Vulnerability& vuln) {
        std::lock_guard<std::mutex> lock(mtx);
        vulnerabilities.push_back(vuln);
    }

    void increment_tests() {
        std::lock_guard<std::mutex> lock(mtx);
        total_tests++;
    }

    void test_passed() {
        std::lock_guard<std::mutex> lock(mtx);
        passed_tests++;
    }

    int get_total_tests() const { return total_tests; }
    int get_passed_tests() const { return passed_tests; }
    int get_vulnerability_count() const { return vulnerabilities.size(); }
    const std::vector<Vulnerability>& get_vulnerabilities() const { return vulnerabilities; }
    
    // 按严重程度统计漏洞
    std::map<Severity, int> get_vulnerability_stats() const {
        std::map<Severity, int> stats;
        stats[LOW] = 0;
        stats[MEDIUM] = 0;
        stats[HIGH] = 0;
        stats[CRITICAL] = 0;
        
        for(const auto& vuln : vulnerabilities) {
            stats[vuln.severity]++;
        }
        return stats;
    }
};

// 扫描配置类
class ScanConfig {
public:
    int threads = 5;                  // 线程数
    int timeout = 15;                 // 超时时间(秒)
    bool ssl_verify = false;          // 是否验证SSL证书
    bool follow_redirects = true;     // 是否跟随重定向
    std::string user_agent = "VulnScanner/1.0";  // 用户代理
    bool aggressive_mode = false;     // 攻击性模式(可能对目标造成影响)
    std::string output_file;          // 报告输出文件
};

// 扫描器基类
class Scanner {
protected:
    std::string target;
    ScanResult result;
    ScanConfig config;

public:
    Scanner(const std::string& t, const ScanConfig& cfg) : target(t), config(cfg) {}
    virtual ~Scanner() = default;
    virtual void scan() = 0;
    const ScanResult& get_result() const { return result; }
    const std::string& get_target() const { return target; }
    const ScanConfig& get_config() const { return config; }
};

// HTTP响应结构体
struct HttpResponse {
    std::string body;
    std::string headers;
    long status_code;
    std::string error;
};

// HTTP请求结构体
struct HttpRequest {
    std::string url;
    std::string method = "GET";
    std::string post_data;
    std::map<std::string, std::string> headers;
};

// HTTP客户端类
class HttpClient {
private:
    CURL* curl;
    ScanConfig config;
    
    // 回调函数
    static size_t write_body(void* contents, size_t size, size_t nmemb, std::string* s) {
        size_t newLength = size * nmemb;
        try {
            s->append((char*)contents, newLength);
        } catch (std::bad_alloc& e) {
            return 0;
        }
        return newLength;
    }
    
    static size_t write_header(void* contents, size_t size, size_t nmemb, std::string* s) {
        return write_body(contents, size, nmemb, s);
    }

public:
    HttpClient(const ScanConfig& cfg) : config(cfg) {
        curl = curl_easy_init();
        if (!curl) {
            throw std::runtime_error("无法初始化CURL");
        }
        
        // 设置默认选项
        curl_easy_setopt(curl, CURLOPT_USERAGENT, config.user_agent.c_str());
        curl_easy_setopt(curl, CURLOPT_TIMEOUT, config.timeout);
        curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, config.follow_redirects ? 1L : 0L);
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, config.ssl_verify ? 1L : 0L);
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, config.ssl_verify ? 2L : 0L);
    }
    
    ~HttpClient() {
        if (curl) {
            curl_easy_cleanup(curl);
        }
    }
    
    HttpResponse send_request(const HttpRequest& req) {
        HttpResponse res;
        std::string response_body;
        std::string response_headers;
        
        if (!curl) {
            res.error = "CURL未初始化";
            return res;
        }
        
        // 设置URL
        curl_easy_setopt(curl, CURLOPT_URL, req.url.c_str());
        
        // 设置方法和POST数据
        if (req.method == "POST") {
            curl_easy_setopt(curl, CURLOPT_POST, 1L);
            curl_easy_setopt(curl, CURLOPT_POSTFIELDS, req.post_data.c_str());
        } else {
            curl_easy_setopt(curl, CURLOPT_HTTPGET, 1L);
        }
        
        // 设置回调
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_body);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response_body);
        curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, write_header);
        curl_easy_setopt(curl, CURLOPT_HEADERDATA, &response_headers);
        
        // 设置头信息
        struct curl_slist* headers = nullptr;
        for (const auto& [name, value] : req.headers) {
            std::string header = name + ": " + value;
            headers = curl_slist_append(headers, header.c_str());
        }
        if (headers) {
            curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
        }
        
        // 执行请求
        CURLcode curl_res = curl_easy_perform(curl);
        
        // 获取状态码
        curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &res.status_code);
        
        // 清理
        if (headers) {
            curl_slist_free_all(headers);
        }
        
        // 处理结果
        if (curl_res != CURLE_OK) {
            res.error = std::string("CURL错误: ") + curl_easy_strerror(curl_res);
        } else {
            res.body = response_body;
            res.headers = response_headers;
        }
        
        return res;
    }
};

// 工具函数类
class Utils {
public:
    // URL编码
    static std::string url_encode(const std::string& s) {
        CURL* curl = curl_easy_init();
        if (!curl) {
            return s;
        }
        
        char* encoded = curl_easy_escape(curl, s.c_str(), s.length());
        std::string result(encoded);
        curl_free(encoded);
        curl_easy_cleanup(curl);
        
        return result;
    }
    
    // 提取URL中的参数
    static std::map<std::string, std::string> extract_params(const std::string& url) {
        std::map<std::string, std::string> params;
        size_t query_pos = url.find('?');
        
        if (query_pos == std::string::npos) {
            return params;
        }
        
        std::string query = url.substr(query_pos + 1);
        size_t pos = 0;
        
        while (pos < query.length()) {
            size_t eq_pos = query.find('=', pos);
            size_t amp_pos = query.find('&', pos);
            
            if (eq_pos == std::string::npos || (amp_pos != std::string::npos && eq_pos > amp_pos)) {
                break;
            }
            
            std::string key = query.substr(pos, eq_pos - pos);
            pos = eq_pos + 1;
            
            size_t value_end = (amp_pos != std::string::npos) ? amp_pos : query.length();
            std::string value = query.substr(pos, value_end - pos);
            pos = value_end + 1;
            
            params[key] = value;
        }
        
        return params;
    }
    
    // 替换URL中的参数值
    static std::string replace_param_value(const std::string& url, const std::string& param, const std::string& value) {
        size_t query_pos = url.find('?');
        if (query_pos == std::string::npos) {
            return url + "?" + param + "=" + value;
        }
        
        std::string base = url.substr(0, query_pos + 1);
        std::string query = url.substr(query_pos + 1);
        std::map<std::string, std::string> params = extract_params(url);
        
        params[param] = value;
        
        std::string new_query;
        for (const auto& [k, v] : params) {
            if (!new_query.empty()) {
                new_query += "&";
            }
            new_query += k + "=" + v;
        }
        
        return base + new_query;
    }
    
    // 检查响应中是否包含敏感信息
    static bool contains_sensitive_info(const std::string& response) {
        std::vector<std::string> patterns = {
            "password", "passwd", "secret", "api_key", "token",
            "session_id", "credit_card", "ssn", "private_key"
        };
        
        std::string lower_response = response;
        std::transform(lower_response.begin(), lower_response.end(), lower_response.begin(), ::tolower);
        
        for (const auto& pattern : patterns) {
            if (lower_response.find(pattern) != std::string::npos) {
                return true;
            }
        }
        return false;
    }
    
    // 获取敏感信息片段
    static std::string get_sensitive_snippet(const std::string& response, int max_length = 100) {
        std::vector<std::string> patterns = {
            "password", "passwd", "secret", "api_key", "token",
            "session_id", "credit_card", "ssn", "private_key"
        };
        
        std::string lower_response = response;
        std::transform(lower_response.begin(), lower_response.end(), lower_response.begin(), ::tolower);
        
        for (const auto& pattern : patterns) {
            size_t pos = lower_response.find(pattern);
            if (pos != std::string::npos) {
                size_t start = (pos > max_length / 2) ? pos - max_length / 2 : 0;
                size_t length = (start + max_length < response.length()) ? max_length : response.length() - start;
                return response.substr(start, length) + "...";
            }
        }
        return "";
    }
    
    // 格式化时间
    static std::string format_time(time_t t) {
        struct tm* timeinfo = localtime(&t);
        char buffer[80];
        strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", timeinfo);
        return std::string(buffer);
    }
};

// Web应用扫描器
class WebScanner : public Scanner {
private:
    HttpClient http_client;
    std::set<std::string> scanned_urls;  // 已扫描的URL，避免重复
    std::mutex url_mutex;
    
    // 检测SQL注入漏洞
    void detect_sql_injection(const std::string& url, const std::string& param) {
        result.increment_tests();
        std::vector<std::pair<std::string, std::string>> payloads = {
            {"基础测试", "' OR 1=1#"}, 
            {"版本探测", "' UNION SELECT 1,version(),3#"},
            {"字段探测", "' AND 1=2 UNION SELECT 1,2,3#"},
            {"破坏测试", "'; DROP TABLE users#"},
            {"时间延迟", "' AND SLEEP(5)#"}
        };

        for(const auto& [desc, payload] : payloads) {
            std::string test_url = Utils::replace_param_value(url, param, Utils::url_encode(payload));
            auto start_time = std::chrono::high_resolution_clock::now();
            
            HttpResponse response = http_client.send_request({test_url});
            
            auto end_time = std::chrono::high_resolution_clock::now();
            auto duration = std::chrono::duration_cast<std::chrono::seconds>(end_time - start_time).count();

            // 检测逻辑
            bool found = false;
            std::string evidence;
            std::string response_snippet;
            
            // 检查SQL错误信息
            if(response.body.find("SQL syntax") != std::string::npos || 
               response.body.find("MySQL server version") != std::string::npos ||
               response.body.find("PostgreSQL") != std::string::npos ||
               response.body.find("ORA-") != std::string::npos ||
               response.body.find("SQLite") != std::string::npos) {
                found = true;
                evidence = desc + " -> 响应包含SQL错误信息";
                size_t snippet_start = response.body.find("SQL syntax");
                if (snippet_start != std::string::npos) {
                    response_snippet = response.body.substr(snippet_start, 200) + "...";
                }
            }
            // 检查数据库版本信息
            else if(response.body.find("5.7.") != std::string::npos || 
                    response.body.find("8.0.") != std::string::npos ||
                    response.body.find("10.") != std::string::npos) {
                found = true;
                evidence = desc + " -> 响应包含数据库版本信息";
            }
            // 检查时间延迟
            else if(payload.find("SLEEP") != std::string::npos && duration >= 4) {
                found = true;
                evidence = desc + " -> 响应延迟 " + std::to_string(duration) + " 秒";
            }

            if(found) {
                Vulnerability vuln;
                vuln.target = url;
                vuln.type = SQL_INJECTION;
                vuln.severity = CRITICAL;
                vuln.description = "检测到可能的SQL注入漏洞，攻击者可能利用此漏洞获取或修改数据库信息。";
                vuln.evidence = evidence;
                vuln.recommendation = "使用参数化查询或预编译语句，对用户输入进行严格过滤和验证。";
                vuln.found_time = time(nullptr);
                vuln.request_payload = payload;
                vuln.response_snippet = response_snippet;
                result.add_vulnerability(vuln);
                break;
            }
        }
        result.test_passed();
    }

    // 检测XSS漏洞
    void detect_xss(const std::string& url, const std::string& param) {
        result.increment_tests();
        std::vector<std::pair<std::string, std::string>> payloads = {
            {"基础脚本", "<script>alert('XSS')</script>"},
            {"图片事件", "<img src=x onerror=alert('XSS')>"},
            {"SVG事件", "<svg onload=alert('XSS')>"},
            {"URL编码", "%3Cscript%3Ealert('XSS')%3C/script%3E"},
            {"变形测试", "<ScRiPt>alert('XSS')</ScRiPt>"}
        };

        for(const auto& [desc, payload] : payloads) {
            std::string encoded_payload = Utils::url_encode(payload);
            std::string test_url = Utils::replace_param_value(url, param, encoded_payload);
            HttpResponse response = http_client.send_request({test_url});

            // 检测逻辑
            bool found = false;
            std::string evidence;
            
            // 检查原始Payload
            if(response.body.find(payload) != std::string::npos) {
                found = true;
                evidence = desc + " -> 响应中包含未过滤的脚本";
            }
            // 检查部分过滤的Payload
            else if(response.body.find("<script") != std::string::npos ||
                    response.body.find("onerror") != std::string::npos ||
                    response.body.find("onload") != std::string::npos) {
                found = true;
                evidence = desc + " -> 响应中包含部分过滤的脚本";
            }

            if(found) {
                Vulnerability vuln;
                vuln.target = url;
                vuln.type = XSS;
                vuln.severity = MEDIUM;
                vuln.description = "检测到可能的跨站脚本(XSS)漏洞，攻击者可能利用此漏洞执行恶意脚本。";
                vuln.evidence = evidence;
                vuln.recommendation = "对用户输入进行严格过滤和编码，设置适当的Content-Security-Policy。";
                vuln.found_time = time(nullptr);
                vuln.request_payload = payload;
                result.add_vulnerability(vuln);
                break;
            }
        }
        result.test_passed();
    }

    // 检测命令注入漏洞
    void detect_command_injection(const std::string& url, const std::string& param) {
        result.increment_tests();
        std::vector<std::pair<std::string, std::string>> payloads = {
            {"基础命令", "| whoami"},
            {"分号命令", "; ls -la"},
            {"&&命令", "&& cat /etc/passwd"},
            {"时间延迟", "; sleep 5"},
            {"URL编码", "%7C%20whoami"}
        };

        for(const auto& [desc, payload] : payloads) {
            std::string test_url = Utils::replace_param_value(url, param, Utils::url_encode(payload));
            auto start_time = std::chrono::high_resolution_clock::now();
            
            HttpResponse response = http_client.send_request({test_url});
            
            auto end_time = std::chrono::high_resolution_clock::now();
            auto duration = std::chrono::duration_cast<std::chrono::seconds>(end_time - start_time).count();

            // 检测逻辑
            bool found = false;
            std::string evidence;
            
            // 检查命令执行结果
            if(response.body.find("root") != std::string::npos || 
               response.body.find("bin") != std::string::npos ||
               response.body.find("etc") != std::string::npos) {
                found = true;
                evidence = desc + " -> 响应包含命令执行结果";
            }
            // 检查时间延迟
            else if(payload.find("sleep") != std::string::npos && duration >= 4) {
                found = true;
                evidence = desc + " -> 响应延迟 " + std::to_string(duration) + " 秒";
            }

            if(found) {
                Vulnerability vuln;
                vuln.target = url;
                vuln.type = COMMAND_INJECTION;
                vuln.severity = CRITICAL;
                vuln.description = "检测到可能的命令注入漏洞，攻击者可能利用此漏洞执行任意系统命令。";
                vuln.evidence = evidence;
                vuln.recommendation = "避免将用户输入直接传递给系统命令函数，使用白名单限制允许的操作。";
                vuln.found_time = time(nullptr);
                vuln.request_payload = payload;
                result.add_vulnerability(vuln);
                break;
            }
        }
        result.test_passed();
    }

    // 检测文件包含漏洞
    void detect_file_inclusion(const std::string& url, const std::string& param) {
        result.increment_tests();
        std::vector<std::pair<std::string, std::string>> payloads = {
            {"相对路径", "../../etc/passwd"},
            {"多级路径", "../../../etc/passwd"},
            {"绝对路径", "/etc/passwd"},
            {"Windows路径", "C:/Windows/system32/drivers/etc/hosts"},
            {"URL编码", "%2E%2E%2Fetc%2Fpasswd"}
        };

        for(const auto& [desc, payload] : payloads) {
            std::string test_url = Utils::replace_param_value(url, param, Utils::url_encode(payload));
            HttpResponse response = http_client.send_request({test_url});

            // 检测敏感文件内容
            if(response.body.find("root:x:0:0:") != std::string::npos ||
               response.body.find("daemon:x:1:1:") != std::string::npos ||
               response.body.find("[hosts]") != std::string::npos) {
                Vulnerability vuln;
                vuln.target = url;
                vuln.type = FILE_INCLUSION;
                vuln.severity = CRITICAL;
                vuln.description = "检测到可能的文件包含漏洞，攻击者可能利用此漏洞读取系统敏感文件。";
                vuln.evidence = desc + " -> 响应中包含敏感系统文件内容";
                vuln.recommendation = "避免使用用户输入直接构建文件路径，使用白名单限制可访问的文件。";
                vuln.found_time = time(nullptr);
                vuln.request_payload = payload;
                result.add_vulnerability(vuln);
                break;
            }
        }
        result.test_passed();
    }

    // 检测CSRF漏洞
    void detect_csrf(const std::string& url) {
        result.increment_tests();
        HttpResponse response = http_client.send_request({url});

        // 检查表单是否包含CSRF令牌
        bool has_csrf_token = false;
        std::vector<std::string> token_patterns = {
            "csrf_token", "csrf", "anti_csrf", "xsrf_token", "token"
        };

        for (const auto& pattern : token_patterns) {
            if (response.body.find(pattern) != std::string::npos) {
                has_csrf_token = true;
                break;
            }
        }

        // 检查是否为状态修改操作
        bool is_state_changing = (url.find("/admin/") != std::string::npos ||
                                 url.find("/delete/") != std::string::npos ||
                                 url.find("/update/") != std::string::npos ||
                                 url.find("/change/") != std::string::npos);

        if (is_state_changing && !has_csrf_token) {
            Vulnerability vuln;
            vuln.target = url;
            vuln.type = CSRF;
            vuln.severity = MEDIUM;
            vuln.description = "检测到可能的跨站请求伪造(CSRF)漏洞，攻击者可能诱导用户执行非预期操作。";
            vuln.evidence = "状态修改操作未包含CSRF令牌";
            vuln.recommendation = "实现CSRF令牌验证机制，检查Referer头，使用SameSite cookie属性。";
            vuln.found_time = time(nullptr);
            result.add_vulnerability(vuln);
        }
        
        result.test_passed();
    }

    // 检测开放重定向
    void detect_open_redirect(const std::string& url, const std::string& param) {
        result.increment_tests();
        std::vector<std::pair<std::string, std::string>> payloads = {
            {"基本重定向", "http://example.com"},
            {"编码重定向", "http%3A%2F%2Fexample.com"},
            {"伪装路径", "/../../http://example.com"},
            {"多斜线", "//example.com"}
        };

        for(const auto& [desc, payload] : payloads) {
            std::string test_url = Utils::replace_param_value(url, param, Utils::url_encode(payload));
            
            // 关闭重定向跟随，以便检测重定向响应
            ScanConfig temp_config = config;
            temp_config.follow_redirects = false;
            HttpClient temp_client(temp_config);
            
            HttpResponse response = temp_client.send_request({test_url});

            // 检测重定向
            if (response.status_code >= 300 && response.status_code < 400) {
                size_t location_pos = response.headers.find("Location:");
                if (location_pos != std::string::npos) {
                    std::string location = response.headers.substr(location_pos + 9);
                    location = location.substr(0, location.find("\r\n"));
                    
                    if (location.find("example.com") != std::string::npos) {
                        Vulnerability vuln;
                        vuln.target = url;
                        vuln.type = OPEN_REDIRECT;
                        vuln.severity = LOW;
                        vuln.description = "检测到可能的开放重定向漏洞，攻击者可能利用此漏洞诱导用户访问恶意网站。";
                        vuln.evidence = desc + " -> 重定向到外部网站: " + location;
                        vuln.recommendation = "使用白名单限制允许重定向的域名，验证并重写重定向URL。";
                        vuln.found_time = time(nullptr);
                        vuln.request_payload = payload;
                        result.add_vulnerability(vuln);
                        break;
                    }
                }
            }
        }
        result.test_passed();
    }

    // 检测敏感信息泄露
    void detect_sensitive_data(const std::string& url) {
        result.increment_tests();
        HttpResponse response = http_client.send_request({url});

        if (Utils::contains_sensitive_info(response.body)) {
            Vulnerability vuln;
            vuln.target = url;
            vuln.type = SENSITIVE_DATA_EXPOSURE;
            vuln.severity = MEDIUM;
            vuln.description = "检测到可能的敏感信息泄露，响应中包含不应公开的敏感数据。";
            vuln.evidence = "响应中包含敏感信息: " + Utils::get_sensitive_snippet(response.body);
            vuln.recommendation = "确保敏感信息不被包含在公开响应中，对敏感数据进行加密或脱敏处理。";
            vuln.found_time = time(nullptr);
            vuln.response_snippet = Utils::get_sensitive_snippet(response.body);
            result.add_vulnerability(vuln);
        }
        
        result.test_passed();
    }

    // 检测Web应用弱密码
    void detect_web_weak_passwords() {
        result.increment_tests();
        std::cout << "[*] 正在检测Web应用弱密码..." << std::endl;

        // 常见登录页路径
        std::vector<std::string> common_login_paths = {
            "/login", "/login.jsp", "/login.do", "/user/login", 
            "/admin/login", "/wp-login.php", "/auth/login",
            "/homepage/login.do", "/system/login", "/account/login"
        };

        // 允许用户补充登录页路径
        std::string custom_login_path;
        std::cout << "请输入自定义登录页路径（如 /xxx/login，无则输入q）: ";
        std::cin >> custom_login_path;
        if (custom_login_path != "q" && !custom_login_path.empty()) {
            common_login_paths.push_back(custom_login_path);
        }

        // 弱密码字典
        std::vector<std::pair<std::string, std::string>> weak_credentials = {
            {"admin", "admin"}, {"admin", "password"}, {"admin", "123456"},
            {"user", "user"}, {"user", "password"}, {"user", "123456"},
            {"root", "root"}, {"root", "password"}, {"root", "123456"},
            {"test", "test"}, {"admin", "12345678"}, {"admin", "admin123"}
        };

        // 检测登录页面并尝试弱密码
        bool login_page_found = false;
        for(const auto& path : common_login_paths) {
            std::string login_url = target + path;
            HttpResponse response = http_client.send_request({login_url});

            // 简单判断是否为登录页
            if(response.body.find("username") != std::string::npos && 
               response.body.find("password") != std::string::npos &&
               (response.body.find("login") != std::string::npos || 
                response.body.find("sign in") != std::string::npos)) {
                
                login_page_found = true;
                std::cout << "[*] 发现登录页面: " << login_url << std::endl;

                // 尝试弱密码
                for(const auto& [user, pass] : weak_credentials) {
                    std::cout << "[*] 尝试登录: " << user << "/" << pass << std::endl;
                    
                    // 构造POST请求
                    HttpRequest req;
                    req.url = login_url;
                    req.method = "POST";
                    req.post_data = "username=" + Utils::url_encode(user) + "&password=" + Utils::url_encode(pass);
                    req.headers["Content-Type"] = "application/x-www-form-urlencoded";
                    
                    HttpResponse login_response = http_client.send_request(req);

                    // 判断登录是否成功（根据跳转或响应内容）
                    if(login_response.status_code == 302 ||  // 登录成功跳转
                       login_response.body.find("dashboard") != std::string::npos ||
                       login_response.body.find("welcome") != std::string::npos ||
                       login_response.body.find("admin panel") != std::string::npos ||
                       login_response.body.find("logout") != std::string::npos) {
                        
                        Vulnerability vuln;
                        vuln.target = login_url;
                        vuln.type = WEAK_PASSWORD;
                        vuln.severity = CRITICAL;
                        vuln.description = "检测到弱密码，攻击者可能通过此凭据登录系统。";
                        vuln.evidence = "用户名: " + user + ", 密码: " + pass + " 登录成功";
                        vuln.recommendation = "立即更改密码，使用强密码策略，启用多因素认证。";
                        vuln.found_time = time(nullptr);
                        vuln.request_payload = "username=" + user + "&password=" + pass;
                        result.add_vulnerability(vuln);
                    }
                }
                break;
            }
        }

        if(!login_page_found) {
            std::cout << "[!] 未发现登录页面，跳过弱密码检测" << std::endl;
        }
        result.test_passed();
    }
    
    // 线程工作函数
    void thread_worker(std::queue<std::pair<std::string, std::string>>& queue) {
        while (true) {
            std::pair<std::string, std::string> task;
            
            // 安全地获取任务
            {
                std::lock_guard<std::mutex> lock(url_mutex);
                if (queue.empty()) {
                    break;
                }
                task = queue.front();
                queue.pop();
            }
            
            std::string url = task.first;
            std::string param = task.second;
            
            std::cout << "[*] 线程 " << std::this_thread::get_id() << " 正在测试: " << url << " 参数: " << param << std::endl;
            
            // 执行各项检测
            detect_sql_injection(url, param);
            detect_xss(url, param);
            detect_command_injection(url, param);
            detect_file_inclusion(url, param);
            detect_open_redirect(url, param);
            detect_sensitive_data(url);
        }
    }

public:
    WebScanner(const std::string& t, const ScanConfig& cfg) : Scanner(t, cfg), http_client(cfg) {}

    void scan() override {
        std::cout << "\n=== 开始Web应用漏洞扫描 ===" << std::endl;
        std::cout << "目标: " << target << std::endl;
        std::cout << "线程数: " << config.threads << std::endl;
        std::cout << "超时时间: " << config.timeout << "秒" << std::endl;

        // 获取用户输入的测试目标
        std::vector<std::pair<std::string, std::string>> test_targets;
        std::string test_url, param_name;
        
        std::cout << "\n请输入需要测试的URL和参数（用于漏洞检测）" << std::endl;
        while (true) {
            std::cout << "请输入测试URL（如 http://example.com/search，输入q结束）: ";
            std::cin >> test_url;
            if (test_url == "q" || test_url.empty()) break;
            
            // 自动添加协议头
            if (test_url.find("http://") == std::string::npos && 
                test_url.find("https://") == std::string::npos) {
                test_url = "http://" + test_url;
                std::cout << "[*] 自动添加协议头: " << test_url << std::endl;
            }
            
            std::cout << "请输入该URL的测试参数（如 id 或 keyword）: ";
            std::cin >> param_name;
            if (!param_name.empty()) {
                test_targets.emplace_back(test_url, param_name);
            } else {
                std::cout << "[!] 参数名不能为空，已跳过该URL" << std::endl;
            }
        }

        // 添加CSRF检测任务
        for (const auto& [url, _] : test_targets) {
            detect_csrf(url);
        }

        // 使用多线程执行其他检测
        if (!test_targets.empty()) {
            std::queue<std::pair<std::string, std::string>> task_queue;
            for (const auto& task : test_targets) {
                task_queue.push(task);
            }
            
            // 创建线程池
            std::vector<std::thread> threads;
            for (int i = 0; i < config.threads && !task_queue.empty(); ++i) {
                threads.emplace_back(&WebScanner::thread_worker, this, std::ref(task_queue));
            }
            
            // 等待所有线程完成
            for (auto& thread : threads) {
                thread.join();
            }
        }

        // 检测弱密码
        detect_web_weak_passwords();

        std::cout << "\n=== Web应用漏洞扫描完成 ===\n" << std::endl;
    }
};

// 系统扫描器
class SystemScanner : public Scanner {
private:
    // 执行系统命令并返回输出结果
    std::string execute_command(const std::string& cmd) {
        char buffer[128];
        std::string result;
        
        // 使用lambda作为删除器避免警告
        using FILE_ptr = FILE*;
        auto deleter = [](FILE_ptr fp) { if (fp) pclose(fp); };
        std::unique_ptr<FILE, decltype(deleter)> pipe(popen(cmd.c_str(), "r"), deleter);
        
        if (!pipe) {
            throw std::runtime_error("popen() failed to execute command");
        }
        
        while (fgets(buffer, sizeof(buffer), pipe.get()) != nullptr) {
            result += buffer;
        }
        
        return result;
    }

    // 比较版本号
    bool version_in_range(const std::string& version, const std::string& vulnerable_range) {
        if (vulnerable_range.empty()) return false;
        
        std::string op;
        if (vulnerable_range.substr(0, 2) == "<=") {
            op = "<=";
        } else if (vulnerable_range.substr(0, 1) == "<") {
            op = "<";
        } else if (vulnerable_range.substr(0, 1) == "=") {
            op = "=";
        } else {
            op = "<="; // 默认比较方式
        }
        
        std::string vuln_version = vulnerable_range.substr(op.length());
        
        // 分割版本号为数字数组
        auto split_version = [](const std::string& v) {
            std::vector<int> parts;
            std::stringstream ss(v);
            std::string part;
            while (std::getline(ss, part, '.')) {
                try {
                    parts.push_back(std::stoi(part));
                } catch (...) {
                    parts.push_back(0); // 非数字部分视为0
                }
            }
            return parts;
        };
        
        auto v1 = split_version(version);
        auto v2 = split_version(vuln_version);
        
        // 对齐版本号长度
        size_t max_len = std::max(v1.size(), v2.size());
        v1.resize(max_len, 0);
        v2.resize(max_len, 0);
        
        // 比较每个部分
        for (size_t i = 0; i < max_len; ++i) {
            if (v1[i] < v2[i]) return op == "<" || op == "<=";
            if (v1[i] > v2[i]) return false;
        }
        
        // 版本号相等
        return op == "=" || op == "<=";
    }

    // 检查文件权限
    void check_file_permissions() {
        result.increment_tests();
        std::cout << "[*] 正在检查文件权限..." << std::endl;

        std::vector<std::string> sensitive_files = {
            "/etc/passwd", "/etc/shadow", "/etc/sudoers",
            "/etc/ssh/sshd_config", "/var/log/auth.log"
        };

        for(const auto& file : sensitive_files) {
            try {
                std::string cmd = "stat -c %a " + file;
                std::string permissions = execute_command(cmd);
                permissions.erase(std::remove_if(permissions.begin(), permissions.end(), 
                                                [](char c) { return std::isspace(c); }), 
                                 permissions.end());

                if(permissions.empty()) {
                    std::cout << "[!] 无法获取 " << file << " 的权限信息" << std::endl;
                    continue;
                }

                // 检查危险权限
                if(file == "/etc/shadow" && permissions != "000" && permissions != "600") {
                    Vulnerability vuln;
                    vuln.target = file;
                    vuln.type = PERMISSION_ISSUE;
                    vuln.severity = CRITICAL;
                    vuln.description = "shadow文件权限不安全，可能导致密码哈希泄露。";
                    vuln.evidence = file + " 权限为 " + permissions;
                    vuln.recommendation = "立即修复shadow文件权限，设置为000或600，仅root用户可读写。";
                    vuln.found_time = time(nullptr);
                    result.add_vulnerability(vuln);
                }
                else if((file == "/etc/passwd" || file == "/etc/sudoers") && 
                        permissions.find('7') != std::string::npos) {
                    Vulnerability vuln;
                    vuln.target = file;
                    vuln.type = PERMISSION_ISSUE;
                    vuln.severity = HIGH;
                    vuln.description = "敏感文件对所有用户开放写权限，可能导致未授权修改。";
                    vuln.evidence = file + " 权限为 " + permissions;
                    vuln.recommendation = "限制敏感文件的权限，移除其他用户的写权限。";
                    vuln.found_time = time(nullptr);
                    result.add_vulnerability(vuln);
                }
            } catch (const std::exception& e) {
                std::cerr << "[!] 检查 " << file << " 权限时出错: " << e.what() << std::endl;
            }
        }
        result.test_passed();
    }

    // 检查系统配置
    void check_system_configurations() {
        result.increment_tests();
        std::cout << "[*] 正在检查系统配置..." << std::endl;

        // 检查SSH配置
        try {
            std::ifstream ssh_config("/etc/ssh/sshd_config");
            if (!ssh_config.is_open()) {
                std::cerr << "[!] 无法打开/etc/ssh/sshd_config，需root权限" << std::endl;
                result.test_passed();
                return;
            }

            std::string line;
            bool permit_root_login = false;
            bool password_authentication = false;

            // 逐行读取配置
            while (std::getline(ssh_config, line)) {
                // 跳过注释行和空行
                if (line.empty() || line[0] == '#') continue;

                // 检查PermitRootLogin配置
                if (line.find("PermitRootLogin") != std::string::npos) {
                    std::string value = line.substr(line.find_last_of(' ') + 1);
                    std::transform(value.begin(), value.end(), value.begin(), ::tolower);
                    if (value == "yes" || value == "prohibit-password") {
                        permit_root_login = true;
                    }
                }

                // 检查PasswordAuthentication配置
                if (line.find("PasswordAuthentication") != std::string::npos) {
                    std::string value = line.substr(line.find_last_of(' ') + 1);
                    std::transform(value.begin(), value.end(), value.begin(), ::tolower);
                    if (value == "yes") {
                        password_authentication = true;
                    }
                }
            }
            ssh_config.close();

            // 报告SSH配置问题
            if (permit_root_login) {
                Vulnerability vuln;
                vuln.target = "SSH服务";
                vuln.type = UNSAFE_CONFIGURATION;
                vuln.severity = MEDIUM;
                vuln.description = "SSH配置允许root用户直接登录，增加了安全风险。";
                vuln.evidence = "PermitRootLogin yes";
                vuln.recommendation = "设置PermitRootLogin no，通过普通用户登录后su或sudo提升权限。";
                vuln.found_time = time(nullptr);
                result.add_vulnerability(vuln);
            }

            if (password_authentication) {
                Vulnerability vuln;
                vuln.target = "SSH服务";
                vuln.type = UNSAFE_CONFIGURATION;
                vuln.severity = MEDIUM;
                vuln.description = "SSH启用了密码认证，建议仅使用密钥认证。";
                vuln.evidence = "PasswordAuthentication yes";
                vuln.recommendation = "设置PasswordAuthentication no，使用SSH密钥认证。";
                vuln.found_time = time(nullptr);
                result.add_vulnerability(vuln);
            }
        } catch (const std::exception& e) {
            std::cerr << "[!] 检查SSH配置时出错: " << e.what() << std::endl;
        }

        result.test_passed();
    }

    // 检查未打补丁的软件
    void check_unpatched_software() {
        result.increment_tests();
        std::cout << "[*] 正在检查未打补丁的软件..." << std::endl;

        // 定义需要检查的软件及其已知漏洞版本范围
        std::vector<std::tuple<std::string, std::string, std::string, std::string>> software_list = {
            {
                "Apache HTTP Server", 
                "apache2 -v | grep 'Server version' | awk '{print $3}' | cut -d'/' -f2", 
                "<=2.4.49",  
                "2.4.50+"
            },
            {
                "OpenSSL", 
                "openssl version | awk '{print $2}'", 
                "<=1.1.1k",  
                "1.1.1l+"
            },
            {
                "MySQL/MariaDB", 
                "mysql --version | awk '{print $5}' | cut -d',' -f1", 
                "<=8.0.27",  
                "8.0.28+"
            },
            {
                "SSH", 
                "ssh -V 2>&1 | awk '{print $1}' | cut -d'_' -f2", 
                "<=8.6p1",   
                "8.7p1+"
            }
        };

        for (const auto& [name, cmd, vuln_range, recommend_version] : software_list) {
            try {
                std::string version = execute_command(cmd);
                // 去除换行符和空格
                version.erase(std::remove_if(version.begin(), version.end(), 
                                            [](char c) { return std::isspace(c); }), 
                             version.end());
                
                if (version.empty()) {
                    std::cout << "[!] 未检测到 " << name << std::endl;
                    continue;
                }
                
                std::cout << "[*] " << name << " 版本: " << version << std::endl;
                
                if (version_in_range(version, vuln_range)) {
                    Vulnerability vuln;
                    vuln.target = name;
                    vuln.type = UNPATCHED_SOFTWARE;
                    vuln.severity = HIGH;
                    vuln.description = name + " " + version + " 版本存在已知安全漏洞，可能被利用。";
                    vuln.evidence = name + " 安装版本: " + version + "，漏洞版本范围: " + vuln_range;
                    vuln.recommendation = "升级" + name + "到" + recommend_version + "版本。";
                    vuln.found_time = time(nullptr);
                    result.add_vulnerability(vuln);
                }
            } catch (const std::exception& e) {
                std::cerr << "[!] 检查 " << name << " 时出错: " << e.what() << std::endl;
            }
        }
        
        result.test_passed();
    }

    // 检查系统用户弱密码
    void check_weak_passwords() {
        result.increment_tests();
        std::cout << "[*] 检查系统用户弱密码..." << std::endl;

        try {
            // 读取shadow文件（需要root权限）
            std::ifstream shadow("/etc/shadow");
            if (!shadow.is_open()) {
                std::cerr << "[!] 无法打开/etc/shadow，需root权限" << std::endl;
                result.test_passed();
                return;
            }

            // 弱密码字典
            std::vector<std::string> weak_passwords = {
                "password", "123456", "12345678", "qwerty", "abc123",
                "123456789", "12345", "1234", "111111", "admin",
                "welcome", "letmein", "1234567", "sunshine", "iloveyou"
            };

            std::string line;
            while (std::getline(shadow, line)) {
                // 解析shadow文件格式: username:password_hash:...)
                size_t colon1 = line.find(':');
                if (colon1 == std::string::npos) continue;
                
                std::string username = line.substr(0, colon1);
                size_t colon2 = line.find(':', colon1 + 1);
                if (colon2 == std::string::npos) continue;
                
                std::string hash = line.substr(colon1 + 1, colon2 - colon1 - 1);

                // 跳过没有密码的用户
                if (hash == "*" || hash == "!" || hash.empty()) continue;

                // 检查弱密码
                for (const std::string& pass : weak_passwords) {
                    // 使用crypt函数验证密码
                    std::string encrypted = crypt(pass.c_str(), hash.c_str());
                    if (encrypted == hash) {
                        Vulnerability vuln;
                        vuln.target = "系统用户 " + username;
                        vuln.type = WEAK_PASSWORD;
                        vuln.severity = CRITICAL;
                        vuln.description = "系统用户使用弱密码，攻击者可能通过暴力破解获取访问权限。";
                        vuln.evidence = "用户 " + username + " 使用了弱密码: " + pass;
                        vuln.recommendation = "立即更改该用户密码，使用强密码策略。";
                        vuln.found_time = time(nullptr);
                        result.add_vulnerability(vuln);
                        break;
                    }
                }
            }
            shadow.close();
        } catch (const std::exception& e) {
            std::cerr << "[!] 检查系统用户弱密码时出错: " << e.what() << std::endl;
        }

        result.test_passed();
    }

public:
    SystemScanner(const std::string& t, const ScanConfig& cfg) : Scanner(t, cfg) {}

    void scan() override {
        std::cout << "\n=== 开始系统漏洞扫描 ===" << std::endl;
        std::cout << "目标: " << target << std::endl;

        // 执行各项系统检测
        check_file_permissions();
        check_system_configurations();
        check_unpatched_software();
        check_weak_passwords();

        std::cout << "\n=== 系统漏洞扫描完成 ===\n" << std::endl;
    }
};

// 报告生成器
class ReportGenerator {
public:
    static void generate_text_report(const Scanner& scanner, const std::string& filename = "") {
        const ScanResult& result = scanner.get_result();
        const std::vector<Vulnerability>& vulns = result.get_vulnerabilities();
        auto stats = result.get_vulnerability_stats();

        // 准备输出流
        std::ostream* out;
        std::ofstream file;
        
        if (!filename.empty()) {
            file.open(filename);
            if (!file.is_open()) {
                std::cerr << "[!] 无法打开输出文件 " << filename << "，将输出到控制台" << std::endl;
                out = &std::cout;
            } else {
                out = &file;
            }
        } else {
            out = &std::cout;
        }

        *out << "\n=============================================" << std::endl;
        *out << "            漏洞扫描报告                      " << std::endl;
        *out << "=============================================" << std::endl;
        *out << "目标: " << scanner.get_target() << std::endl;
        *out << "扫描时间: " << Utils::format_time(time(nullptr)) << std::endl;
        *out << "总测试数: " << result.get_total_tests() << std::endl;
        *out << "通过测试: " << result.get_passed_tests() << std::endl;
        *out << "发现漏洞总数: " << result.get_vulnerability_count() << std::endl;
        *out << "漏洞严重程度分布:" << std::endl;
        *out << "  - CRITICAL: " << stats[CRITICAL] << std::endl;
        *out << "  - HIGH: " << stats[HIGH] << std::endl;
        *out << "  - MEDIUM: " << stats[MEDIUM] << std::endl;
        *out << "  - LOW: " << stats[LOW] << std::endl;

        if (!vulns.empty()) {
            *out << "\n---------------------------------------------" << std::endl;
            *out << "              发现的漏洞详情                  " << std::endl;
            *out << "---------------------------------------------" << std::endl;
            
            for (size_t i = 0; i < vulns.size(); ++i) {
                const auto& vuln = vulns[i];
                *out << "\n漏洞 " << (i + 1) << ":" << std::endl;
                *out << "类型: " << vuln.type_to_string() << std::endl;
                *out << "严重程度: " << vuln.severity_to_string() << std::endl;
                *out << "目标: " << vuln.target << std::endl;
                *out << "发现时间: " << Utils::format_time(vuln.found_time) << std::endl;
                *out << "描述: " << vuln.description << std::endl;
                *out << "证据: " << vuln.evidence << std::endl;
                
                if (!vuln.request_payload.empty()) {
                    *out << "测试载荷: " << vuln.request_payload << std::endl;
                }
                
                if (!vuln.response_snippet.empty()) {
                    *out << "响应片段: " << vuln.response_snippet << std::endl;
                }
                
                *out << "修复建议: " << vuln.recommendation << std::endl;
                *out << "---------------------------------------------" << std::endl;
            }
        }
        
        *out << "\n=============================================" << std::endl;
        *out << "            报告结束                          " << std::endl;
        *out << "=============================================" << std::endl;
        
        if (file.is_open()) {
            file.close();
            std::cout << "\n报告已保存到 " << filename << std::endl;
        }
    }
};

int main() {
    // 初始化CURL
    curl_global_init(CURL_GLOBAL_DEFAULT);
    
    std::cout << "=== 高级漏洞扫描工具 ===" << std::endl;

    // 配置扫描参数
    ScanConfig config;
    std::string input;
    
    std::cout << "\n请配置扫描参数:" << std::endl;
    std::cout << "线程数 (默认5): ";
    std::getline(std::cin, input);
    if (!input.empty()) {
        try {
            config.threads = std::stoi(input);
        } catch (...) {
            std::cout << "使用默认线程数: 5" << std::endl;
        }
    }
    
    std::cout << "超时时间(秒) (默认15): ";
    std::getline(std::cin, input);
    if (!input.empty()) {
        try {
            config.timeout = std::stoi(input);
        } catch (...) {
            std::cout << "使用默认超时时间: 15秒" << std::endl;
        }
    }
    
    std::cout << "验证SSL证书? (y/n, 默认n): ";
    std::getline(std::cin, input);
    config.ssl_verify = (input == "y" || input == "Y");
    
    std::cout << "输出报告文件 (默认不输出): ";
    std::getline(std::cin, input);
    if (!input.empty()) {
        config.output_file = input;
    }

    // 获取Web应用目标
    std::string web_target;
    std::cout << "\n请输入要扫描的Web应用URL: ";
    std::getline(std::cin, web_target);

    // 扫描Web应用
    WebScanner web_scanner(web_target, config);
    web_scanner.scan();
    ReportGenerator::generate_text_report(web_scanner, config.output_file.empty() ? "" : config.output_file + "_web.txt");

    // 获取系统目标
    std::string system_target;
    std::cout << "\n请输入要扫描的系统主机名或IP (本地输入localhost): ";
    std::getline(std::cin, system_target);

    // 扫描系统
    SystemScanner system_scanner(system_target, config);
    system_scanner.scan();
    ReportGenerator::generate_text_report(system_scanner, config.output_file.empty() ? "" : config.output_file + "_system.txt");

    // 清理CURL
    curl_global_cleanup();
    
    return 0;
}
